// ----------------------------------------------------------------------------
// serialize_instance_member.cpp
// ----------------------------------------------------------------------------
#include <fw/base/serialize/serialize_instance_member.h>
#include <fw/base/serialize/serialize_type.h>
#include <fw/base/serialize/serialize_member.h>
#include <fw/base/serialize/serialize_schema.h>
#include <fw/base/serialize/byte_reader.h>
#include <fw/base/serialize/byte_writer.h>

namespace fw
{
	SerializeInstanceMember::SerializeInstanceMember(int count, Hash typeName)
	: SerializeMember(count, typeName)
	{
	}
	
	size_t SerializeInstanceMember::GetSize() const
	{
		return GetType()->GetSize();
	}
	
	size_t SerializeInstanceMember::GetAlignment() const
	{
		return GetType()->GetAlignment();
	}
	
	int SerializeInstanceMember::GetPointerCount(const char *scopeData, int index) const
	{
		return 0;
	}
	
	void SerializeInstanceMember::Convert(char*						dstData,
										  const char*				srcData,
										  const SerializeMember&	srcMember,
										  SerializeAllocator&		alloc) const
	{
		for(int index=0; index<GetCount(); ++index)
		{
			char*		dstMemberData = GetDataPtr(dstData, index);
			const char* srcMemberData = srcMember.GetDataPtr(srcData, index);
			GetType()->ConvertOne(dstMemberData, srcMemberData, srcMember.GetType(), alloc, 1);
		}
	}
	
	const SerializeType* SerializeInstanceMember::PreFixUp(SerializeSchema& schema, Hash typeName)
	{
		schema.FixUp(typeName);
		return schema.FindType(typeName);
	}
	
	void SerializeInstanceMember::Write(ByteWriter& writer) const
	{
		uint8_t code = kByteCode_Instance;
		
		if(GetCount() > 1)
		{
			code |= kByteCodeFlag_Array;
		}
		
		writer.Write8 (code);
		writer.Write32(GetTypeName());
		if(code & kByteCodeFlag_Array)
		{
			writer.Write16(GetCount());
		}
	}
	
	SerializeInstanceMember* SerializeInstanceMember::ReadNew(fw::ByteReader &reader)
	{
		size_t rollBack = reader.Tell();
		SerializeInstanceMember* member = nullptr;
		
		uint8_t code = reader.Read8();
		
		if((code & kByteCode_Mask) == kByteCode_Instance)
		{
			int count = 1;
			
			Hash typeName = reader.Read32();
			if(code & kByteCodeFlag_Array)
			{
				count = reader.Read16();
			}
			member = new SerializeInstanceMember(count, typeName);
		}
		if(!member)
		{
			reader.Seek(rollBack);
		}
		return member;
	}
	
	
} // namespace fw
